#ifndef LIST_H
#define LIST_H

#include "types.h"
#include "klib.h"

typedef struct _list_node_t{
    struct _list_node_t *prev;
    struct _list_node_t *next;
}list_node_t;

static inline void list_node_init(list_node_t *node){
    ASSERT(node!= (list_node_t *)0);
    node->prev=node->next=(list_node_t *)0;
}
typedef struct _list_t{
    list_node_t *first;
    list_node_t *last;
    int count;
}list_t;
void list_init(list_t *list);
static inline int list_empty(list_t *list){
    return list->count==0;
}
static inline int list_count(list_t *list){
    return list->count;
}
static inline list_node_t *list_first(list_t *list){
    return list->first;
}
static inline list_node_t *list_last(list_t *list){
    return list->last;
}

void list_insert_first(list_t *list,list_node_t *node);
void list_insert_last(list_t *list,list_node_t *node);

list_node_t *list_remove_first(list_t *list);
list_node_t *list_remove_last(list_t *list);
list_node_t *list_remove(list_t *list,list_node_t *node);

void list_traverse(list_t *list,void (*func)(list_node_t *node));


#define offset_in_parent(type,member) (uint32_t)(&((type *)0)->member)
#define container_of(ptr,type,member) (type*)(ptr ? (uint32_t)ptr-offset_in_parent(type,member) : (uint32_t)0)
#endif